#include "message.h"

namespace cs
{
	message::message(): 
		msg_size_(0), id_(0), sender_(0), receiver_(0)
	{}

	message::message(const message& msg)
	{
		header_ = msg.header_; payload_ = msg.payload_; msg_size_ = msg.msg_size_;
		id_ = msg.id_; sender_ = msg.sender_; receiver_ = msg.receiver_;
	}

	message::message(uint16_t id, address sender, address receiver):
		id_(id), sender_(sender), receiver_(receiver), msg_size_(0)
	{}

	message::message(uint16_t id, address sender, address receiver, std::string payload):
		id_(id), sender_(sender), receiver_(receiver), payload_(payload), msg_size_(0)
	{}

	uint16_t message::id() const 
	{
		return id_;
	}

	address message::sender() const
	{
		return sender_;
	}

	address message::receiver() const
	{
		return receiver_;
	}

	size_t message::size() const 
	{
		return msg_size_;
	}

	std::string message::get() const
	{
		return payload_;
	}

	void message::set(const std::string& payload)
	{
		payload_ = payload;
	}

	message::header_t& message::get_header()
	{
		return header_;
	}

	std::string message::serialize()
	{
		calculate_size();
		encode_header();
		return std::string(header_.data(), header_.size()) + payload_;
	}

	message::operator std::string()
	{
		return serialize();
	}

	void message::calculate_size()
	{
		msg_size_ = payload_.size();
	}

	bool message::decode_header()
	{
		decode(msg_size_, 0);
		decode(id_,		  sizeof(msg_size_));
		decode(sender_,   sizeof(msg_size_) + sizeof(id_));
		decode(receiver_, sizeof(msg_size_) + sizeof(id_) + sizeof(id_));

		return (msg_size_ > 0);
	}

	void message::encode_header()
	{
		encode_size();
		encode_id();
		encode_sender();
		encode_receiver();
	}
		
	void message::encode_size()
	{
		header_[0] = static_cast<char>(((msg_size_ >> 24) & 0xFF));
		header_[1] = static_cast<char>(((msg_size_ >> 16) & 0xFF));
		header_[2] = static_cast<char>(((msg_size_ >> 8) & 0xFF));
		header_[3] = static_cast<char>(((msg_size_ >> 0) & 0xFF));
	}
	
	void message::encode_id()
	{
		header_[4] = static_cast<char>(((id_ >> 8) & 0xFF));
		header_[5] = static_cast<char>(((id_ >> 0) & 0xFF));
	}
	
	void message::encode_sender()
	{
		header_[6] = static_cast<char>(((sender_ >> 8) & 0xFF));
		header_[7] = static_cast<char>(((sender_ >> 0) & 0xFF));
	}

	void message::encode_receiver()
	{
		header_[8] = static_cast<char>(((receiver_ >> 8) & 0xFF));
		header_[9] = static_cast<char>(((receiver_ >> 0) & 0xFF));
	}
}